home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 3
/
Cream of the Crop 3.iso
/
comm
/
wnos5src.zip
/
SLIP.C
< prev
next >
Wrap
Text File
|
1993-08-22
|
3KB
|
137 lines
/* Send and receive IP datagrams on serial lines. Compatible with SLIP
* under Berkeley Unix.
*/
#include <stdio.h>
#include "global.h"
#include "config.h"
#include "mbuf.h"
#include "iface.h"
#include "config.h"
#include "internet.h"
#include "ip.h"
#include "ax25.h"
#include "slip.h"
#include "asy.h"
#include "trace.h"
/* Slip level control structure */
struct slip Slip[ASY_MAX];
/* Send routine for point-to-point slip
* This is a trivial function since there is no slip link-level header
*/
int
slip_send(
struct mbuf *bp, /* Buffer to send */
struct iface *iface, /* Pointer to interface control block */
int32 gateway, /* Ignored (SLIP is point-to-point) */
int prec,int del,int tput,int rel)
{
if(iface == NULLIF) {
free_p(bp);
return -1;
}
return (*iface->raw)(iface,bp);
}
/* Send a raw slip frame -- also trivial */
int
slip_raw(struct iface *iface,struct mbuf *bp)
{
int c;
char *cp;
struct mbuf *lbp;
dump(iface,IF_TRACE_OUT,Slip[iface->xdev].type,bp);
/* Allocate output mbuf that's twice as long as the packet.
* This is a worst-case guess (consider a packet full of FR_ENDs!)
*/
lbp = alloc_mbuf((2 * len_p(bp)) + 2);
cp = lbp->data;
/* Flush out any line garbage */
*cp++ = FR_END;
/* Copy input to output, escaping special characters */
while((c = PULLCHAR(&bp)) != -1){
switch(c){
case FR_ESC:
*cp++ = FR_ESC;
*cp++ = T_FR_ESC;
break;
case FR_END:
*cp++ = FR_ESC;
*cp++ = T_FR_END;
break;
default:
*cp++ = c;
}
}
*cp++ = FR_END;
lbp->cnt = cp - lbp->data;
return Slip[iface->xdev].send(iface->dev,lbp);
}
/* Process SLIP line input */
void
asy_rx(int dev,void *p1,void *p2)
{
int c;
struct phdr phdr;
struct slip *sp = &Slip[dev];
for(;;) {
if((c = sp->get(sp->iface->dev)) == FR_ESC) {
sp->escaped |= SLIP_FLAG;
} else if(c == FR_END) {
struct mbuf *bp = sp->rbp;
sp->rbp = NULLBUF;
sp->rcnt = 0;
if(bp != NULLBUF) {
struct mbuf *nbp = pushdown(bp,sizeof(struct phdr));
phdr.iface = sp->iface;
phdr.type = sp->type;
memcpy(&nbp->data[0],(char *)&phdr,sizeof(struct phdr));
enqueue(&Hopper,nbp);
}
} else {
if(sp->escaped & SLIP_FLAG) {
/* Translate 2-char escape sequence back to original char */
sp->escaped &= ~SLIP_FLAG;
switch(c) {
case T_FR_ESC:
c = FR_ESC;
break;
case T_FR_END:
c = FR_END;
break;
default:
sp->errors++;
break;
}
}
/* We reach here with a character for the buffer;
* make sure there's space for it
*/
if(sp->rbp == NULLBUF) {
/* Allocate first mbuf for new packet */
sp->rbp1 = sp->rbp = alloc_mbuf(sp->iface->mtu);
sp->rcp = sp->rbp->data;
} else if(sp->rbp1->cnt == sp->iface->mtu) {
/* Current mbuf is full; link in another */
sp->rbp1->next = alloc_mbuf(sp->iface->mtu);
sp->rbp1 = sp->rbp1->next;
sp->rcp = sp->rbp1->data;
}
/* Store the character, increment fragment and total
* byte counts
*/
*sp->rcp++ = c;
sp->rbp1->cnt++;
sp->rcnt++;
}
}
}